package me.xsomnus.study.jike.data_structure;

import java.util.Arrays;

/**
 * @author 003387_xiawenye
 * @since 2019/11/20 09:53:38
 */
public class Array<E> {


    private static final int DEFAULT_CAPACITY = 16;
    private static final float DEFAULT_FACTOR = 0.75f;

    /**
     * 存放元素的地方
     */
    private E[] elements;

    /**
     * 数组的大小
     */
    private int size;

    /**
     * 指定数据的容量
     */
    private int capacity;


    private float loadFactor;


    public Array(int capacity, float loadFactor) {
        this.capacity = capacity;
        this.loadFactor = loadFactor;
        this.elements = (E[]) new Object[capacity];
    }


    public Array(int capacity) {
        this(capacity, DEFAULT_FACTOR);
    }

    public Array() {
        this(DEFAULT_CAPACITY, DEFAULT_FACTOR);
    }

    public void add(E e) {
        checkCapacity();
        elements[size++] = e;
    }

    public E delete(int index) {
        checkIndex(index);
        final E target = elements[index];
        if (size - index + 1 >= 0) System.arraycopy(elements, index + 1, elements, index + 1 - 1, size - index + 1);
        size--;
        // 要是删除元素太多，数组也是需要重新缩容的，避免占用大量的内存空间
        ensureSize();
        return target;
    }

    private void ensureSize() {

        if (size < capacity * 0.5f) {

        }
    }

    public void update(int index, E e) {

    }

    private void checkIndex(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index " + index + " is illegal");
        }
    }

    private void checkCapacity() {
        if (size >= capacity * loadFactor) {
            resize();
        }
    }


    private void resize() {
        int newCapacity = capacity << 1;
        E[] newElements = (E[]) new Object[newCapacity];
        System.arraycopy(elements, 0, newElements, 0, size);
        this.elements = null;
        this.elements = newElements;
        this.capacity = newCapacity;
    }

    public int size() {
        return size;
    }

    @Override
    public String toString() {
        return "Array{" +
                "elements=" + Arrays.toString(elements) +
                ", size=" + size +
                ", capacity=" + capacity +
                ", loadFactor=" + loadFactor +
                '}';
    }
}
